<?php
/**
 * Created by PhpStorm.
 * User: lixy
 * Date: 2015/12/24
 * Time: 14:36
 */

namespace app\lib;

use Yii;
use app\models\weixin\T_WXMALL_USER;
class WeixinUtils
{
    //检查公众号接口回调
    public static function checkSignature()
    {
        // you must define TOKEN by yourself
        if (!defined("TOKEN")) {
            throw new Exception('TOKEN is not defined!');
        }

        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];

        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        // use SORT_STRING rule
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );

        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
    //获取微信token
    //远程获取 微信token
    //{"access_token":"-kJLQFqB6swX1ZIKLiTT2eip8nMw9UI46plhM-BYHxM9EsFZui-cfwLnQ9lUWtNIBXubZ_6_QBvgv2OXb-BYPmVkd5kXLHNFOwgvwvLm8bQQYUdAHAWEA","expires_in":7200}
    private function curl_get_weixin_token_file(){
        $APPID = APPID;
        $AppSecret = AppSecret;

        //去微信获取，然后保存
        $TOKEN =  Tools::curl("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$AppSecret");
        $TOKEN_json = json_decode($TOKEN,true);
        $TOKEN_json['get_token_time'] = time();
        file_put_contents($this->weixin_token_file(),json_encode($TOKEN_json));//保存到本地
        return $TOKEN_json;
    }
    private function weixin_token_file(){

        return Yii::$app->basePath.'/tmpAccessToken.php';
    }

    //本地获取 微信token（如果不成功或者超时，就去远程获取）
    public  static   function   get_weixin_token_file(){
        $now_time = time();
        $wx=new WeixinUtils();
        //判断本地的weixin_token是否存在
        if(file_exists($wx->weixin_token_file())){
            //去微信获取，然后保存
            $get_local_token = file_get_contents($wx->weixin_token_file());
            $token_array = json_decode($get_local_token,true);
        } else{
            //去微信获取，然后保存
            $token_array = $wx->curl_get_weixin_token_file();
        }


        //判断 当前时间 减去 本地获取微信token的时间 大于7000秒 ,就要重新获取
        if( $now_time - $token_array['get_token_time'] >7000 ){
            $token_array = $wx->curl_get_weixin_token_file();
        }


        return  $token_array['access_token'];
    }



    private function curl_get_weixin_token_memcache(){
        $APPID = APPID;
        $AppSecret = AppSecret;
        $cache=\Yii::$app->cache;
        //去微信获取，然后保存
        $TOKEN =  Tools::curl("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$AppSecret");
        $TOKEN_json = json_decode($TOKEN);
        $TOKEN_json->get_token_time = time();

        $TOKEN_json->get_jsapi_ticket = static::get_jsapi_ticket($TOKEN_json);


        $TOKEN_json->get_api_ticket = static::get_api_ticket($TOKEN_json);



        $cache->set("weixin_access_token",$TOKEN_json);
        return $TOKEN_json;
    }


    /*
     *      获取accesstoken  emcache
         demo:
        WeixinUtils::get_weixin_token_memcache();

        */

    public  static   function   get_weixin_token_memcache(){
        $now_time = time();
        $cache=\Yii::$app->cache;

        //判断本地的weixin_token是否存在


        $token_object =  $cache->get("weixin_access_token");

        if ($token_object === false) {
            $token_object = WeixinUtils::curl_get_weixin_token_memcache();
        }


        //判断 当前时间 减去 本地获取微信token的时间 大于7000秒 ,就要重新获取
        if( $now_time - $token_object->get_token_time >7000 ){
            $token_object = WeixinUtils::curl_get_weixin_token_memcache();
        }


        return  $token_object;
    }


    private  function getWeixinOauthUrl($REDIRECT_URI,$STATE,$SCOPE=false){

        if($SCOPE){
            $SCOPE='snsapi_userinfo';
        }else{
            $SCOPE='snsapi_base';
        }
        $APPID = APPID;
        $REDIRECT_URI=urlencode($REDIRECT_URI);

        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$APPID&redirect_uri=$REDIRECT_URI&response_type=code&scope=$SCOPE&state=$STATE#wechat_redirect";
    }
    //获取页面token信息
    /*{
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE",
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }*/
    private   function getWeixin_WebAccess_Token($CODE){
        $APPID = APPID;
        $AppSecret = AppSecret;
        $re =  Tools::curl("https://api.weixin.qq.com/sns/oauth2/access_token?appid=$APPID&secret=$AppSecret&code=$CODE&grant_type=authorization_code");
        $re=json_decode($re);
        //{"errcode":40029,"errmsg":"invalid code"}
        if (isset($re->errcode)) {
            echo '<h1>错误：</h1>'.$re->errcode;
            echo '<br/><h2>错误信息：</h2>'.$re->errmsg;
            die;
        }else{
            return $re;
        }
    }
//检验授权凭证（access_token）是否有效
//https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
    /*正确的Json返回结果：

    { "errcode":0,"errmsg":"ok"}
    错误时的Json返回示例：

    { "errcode":40003,"errmsg":"invalid openid"}
    */
    private   function getWeixin_WebAccess_Token_check($ACCESS_TOKEN,$OPENID){

        $re =  Tools::curl("https://api.weixin.qq.com/sns/auth?access_token=$ACCESS_TOKEN&openid=$OPENID");
        $re=json_decode($re);
        if($re->errcode=='0'){
            return true;
        }else{
            return false;
        }

    }
    private  function WebAuthRedirect($REDIRECT_URI){
        ob_end_clean();
        $url=WeixinUtils::getWeixinOauthUrl($REDIRECT_URI,"dorabox_weixin_web_auth",true);
        header("Location: $url");
        exit;
    }
    /*
     * 获取微信网页授权
     * 注意！！！！！！！！！最好放第一行，因为这个可能跳转并回调回来！！！！！！！
      $web_token_data=WeixinUtils::GET_WebAuthData();

    var_dump( $web_token_data);
    */
    public  static function GET_WebAuthData(){
        $session = Yii::$app->session;

        if(empty($_GET["state"])) {

            $key = 'web_token_data';
            //检查是否session存在web_token_data
            if ($session->has($key)) {
                $web_token_data = $session->get($key);
                //检查token是否有效
                $re = WeixinUtils::getWeixin_WebAccess_Token_check($web_token_data->access_token, $web_token_data->openid);
                if ($re) {//有效 返回数据
                    return $web_token_data;
                }else{

                    echo "授权失败,请刷新页面";
                    $session->remove($key);//移除无效的session key
                    die;
                }
            }

            //全新的取token
            WeixinUtils::WebAuthRedirect(Yii::$app->request->absoluteUrl);

        }else {
            if ($_GET["state"] == 'dorabox_weixin_web_auth') {
                if (empty($_GET['code'])) {
                    echo "授权失败";
                    die;
                } else {
                    $code = $_GET['code'];

                    $web_token_data = WeixinUtils::getWeixin_WebAccess_Token($code);
                    $session->set("web_token_data", $web_token_data);
                    //移除state
                    $url=Yii::$app->request->absoluteUrl;
                    $url= str_replace('&state=dorabox_weixin_web_auth','',$url);
                    header("Location: $url");
                    exit;
                    //在分享朋友的时候回带上一堆参数
//                    return $web_token_data;
                }
            } else {
                //忽略不是回调回来的
            }


        }



    }

//    获取微信用户信息
    private static function get_weixin_userinfo($web_token_data){
        $url="https://api.weixin.qq.com/sns/userinfo?access_token=$web_token_data->access_token&openid=$web_token_data->openid&lang=zh_CN";
        $re =  Tools::curl($url);
        return json_decode($re);
    }
    public static function weixin_userinfo_filter(){
        $session = Yii::$app->session;
        $key="user_info";


        if (YII_ENV=='dev') {
            //调试用---begin
//            $session->remove($key);
//            $userinfo = (object)null;
//            $userinfo->userid = '8ebe86b4-57ab-2fe1-77e5-6209e11f08ac';
//            $userinfo->openid = 'oTJVss0fVh-xou1H-tVyNnijmDyk';
//            $userinfo->headimgurl = '';
//            $userinfo->nickname = '测试用户';
//            $session->set($key, $userinfo);
//            return $session->get($key);
            //-----end
        }

        if($session->has($key)){
            //pass
        }else{
            $web_token_data=static::GET_WebAuthData();
            $userinfo= static::get_weixin_userinfo($web_token_data);
            //写入数据库  WX_OPENID,NICK_NAME,HEADER_URL
            $datas['WX_OPENID']=$userinfo->openid;
            $datas['NICK_NAME']=$userinfo->nickname;
            $datas['HEADER_URL']=$userinfo->headimgurl;
            $userinfo->userid=T_WXMALL_USER::addUser($datas);
//            写入session
            $session->set($key,$userinfo);

        }
        return $session->get($key);

    }
//获取jsapi_ticket
    /*object(stdClass)[60]
    public 'access_token' => string 'ZKiVxXdJM9uixPTtThNA0La9bdkqnfzYTGLWK4eawJEyucGbwLX5Zni3880FczUeW8uvBWQCj9CJVEJ-RuuD1BbG_9ozxbPMRR2GJbtolC4LIQgAFAAXF' (length=117)
    public 'expires_in' => int 7200
    public 'get_token_time' => int 1451272119
    public 'get_jsapi_ticket' =>
    object(stdClass)[61]
    public 'errcode' => int 0
    public 'errmsg' => string 'ok' (length=2)
    public 'ticket' => string 'kgt8ON7yVITDhtdwci0qeRge_U6TGk7GEx0Tq-siTNYXCeFwckJzW2TS3Hjn3SJErhLZeYBsqGTAlgGgeW7Q6A' (length=86)
    public 'expires_in' => int 7200*/
    private  static function get_jsapi_ticket($web_token_data){
        $url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$web_token_data->access_token&type=jsapi";
        $re =  Tools::curl($url);
        return json_decode($re);

    }
    private  static function get_api_ticket($web_token_data){
        $url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$web_token_data->access_token&type=wx_card";
        $re =  Tools::curl($url);
        return json_decode($re);

    }
//获取微信jssdk conf参数
    public static function getJs_SignPackage() {
        $appId = APPID;


        $access_token= WeixinUtils::get_weixin_token_memcache();
        $jsapiTicket=$access_token->get_jsapi_ticket->ticket;

        $url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        $timestamp = time();
        $nonceStr = WeixinUtils::createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

        $signature = sha1($string);

        $signPackage = array(

            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,

        );
        return $signPackage;
    }

    public static function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    //获取微信jssdk conf参数
    private function getCardSign($card){
        sort($card,SORT_STRING);
        $sign = sha1(implode($card));
        if (!$sign)
            return false;
        return $sign;
    }
    /*获取卡卷 cardExt
     * array (size=7)
    'api_ticket' => string 'IpK_1T69hDhZkLQTlwsAX_241-_SbC_qxY1FgG7Wpkw2H3rt9WjmI9BR9Yi9lZNIzlMEvESpJWjZTtS1vv70ug' (length=86)
    'nonce_str' => string '3TojENThEBYPI3z0' (length=16)
    'timestamp' => int 1451283734
    'card_id' => string '123' (length=3)
    'code' => string '' (length=0)
    'openid' => string '' (length=0)
    'signature' => string 'b3066e5babb21caeef4c655bf78e00a9126367db' (length=40)*/
    public static function getApi_ticket_SignPackage( $card_id,$code="",$openid="") {
        $access_token= WeixinUtils::get_weixin_token_memcache();
        $apiTicket=$access_token->get_api_ticket->ticket;
        $timestamp = time();
        $nonceStr = WeixinUtils::createNonceStr();
//api_ticket、timestamp、card_id、code、openid、nonce_str
        $signPackage = array(
            "api_ticket"=>$apiTicket,
            "nonce_str"  => $nonceStr,
            "timestamp" => $timestamp,
            "card_id"  => $card_id,
            "code"=>$code,
            "openid"=>$openid,
        );
        $signature=WeixinUtils::getCardSign($signPackage);
        $signPackage["signature"]=$signature;

        return $signPackage;
    }
    /**
     * 文本类型回复
     * @param $object  发送对象
     * @param $content 内容
     * @return string xml内容
     *
    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>12345678</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你好]]></Content>
    </xml>
     */
    public  static function _response_text($object,$content){

        $textTpl = "<xml>
                <ToUserName><![CDATA[%s]]></ToUserName>
                <FromUserName><![CDATA[%s]]></FromUserName>
                <CreateTime>%s</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[%s]]></Content>

                </xml>";
        $resultStr = sprintf($textTpl, $object->ToUserName, $object->FromUserName, time(), $content);
        return $resultStr;
    }
    //图文消息
    public  static function _response_news($object,$content){
        $time=time();
        $ArticleCount=count($content);
        $content=implode("\r\n",$content);
        $textTpl = "<xml>
            <ToUserName><![CDATA[$object->ToUserName]]></ToUserName>
            <FromUserName><![CDATA[$object->FromUserName]]></FromUserName>
            <CreateTime>$time</CreateTime>
            <MsgType><![CDATA[news]]></MsgType>
            <ArticleCount>$ArticleCount</ArticleCount>
            <Articles>
                 $content
            </Articles>
            </xml> ";
        Yii::trace($textTpl);
        return $textTpl;
    }

    public static function _news_Article($item){
        $item=(object)$item;
        return "<item>
            <Title><![CDATA[$item->title]]></Title>
            <Description><![CDATA[$item->description]]></Description>
            <PicUrl><![CDATA[$item->picurl]]></PicUrl>
            <Url><![CDATA[$item->url]]></Url>
            </item>";
    }
    public static function _createMenu($menus_jsonStr){

        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=$token_object->access_token";
        $re =  Tools::postJson($url,$menus_jsonStr,true);
        return json_decode($re);
    }

    public static function _getMenu(){

        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/menu/get?access_token=$token_object->access_token";
        $re =  Tools::curl($url);
        return json_decode($re);
    }
    /*$p='{
                "type":"news",
                "offset":0,
                "count":20
            }';
    $re=WeixinUtils::_getBatchget_material(json_decode($p));
    var_dump($re);*/
//获取素材库
    public static function _getBatchget_material($jsonData){

        $token_object=static ::get_weixin_token_memcache();

        $url="https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=$token_object->access_token";
        $re =  Tools::postJson($url,$jsonData,true);

        return json_decode($re);
    }
    //临时推广二维码
//http请求方式: POST
//URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
//POST数据格式：json
//POST数据例子：{"expire_seconds": 2592000, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 1}}}
//1  2016-1-15活动
//object(stdClass)#29 (3) { ["ticket"]=> string(96) "gQG08DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0t6bExsQmJsdTIzQ3VqbHFUQmNKAAIEumCgVgMEAI0nAA==" ["expire_seconds"]=> int(2592000) ["url"]=> string(43) "http://weixin.qq.com/q/KzlLlBblu23CujlqTBcJ" }
//https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket
    public  static function qrcode_temp($scene_key){
        //echo json_encode(['expire_seconds'=>2592000,'action_name'=>'QR_SCENE','action_info'=>['scene'=>['scene_id'=>1]]]);
        //die();
        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$token_object->access_token";
        $re =  Tools::postJson($url,['expire_seconds'=>2592000,'action_name'=>'QR_SCENE','action_info'=>['scene'=>['scene_id'=>$scene_key,]]]);
        return json_decode($re);

    }
/*永久二维码请求说明
http请求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST数据格式：json
POST数据例子：{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}
或者也可以使用以下POST数据创建字符串形式的二维码参数：
{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "123"}}}*/
    public  static function qrcode_forever($scene_key,$scene_str=''){

        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$token_object->access_token";
        $re =  Tools::postJson($url,['action_name'=>'QR_LIMIT_STR_SCENE','action_info'=>['scene'=>['scene_str'=>$scene_key,'scene_str'=>$scene_str]]]);
        return json_decode($re);

    }

    //    获取微信用户信息
    public static function get_weixin_userinfo_base($openid){
        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=$token_object->access_token&openid=$openid&lang=zh_CN";
        $re =  Tools::curl($url);
        return json_decode($re);
    }
    //    发送模板消息
    public static function sendTemplateMsg($template_id,$openid,$href_url,$data){
        $p=[
            'touser'=>$openid,
            'template_id'=>$template_id,
            'url'=>$href_url,
            'data'=>$data
        ];
       /* {
            "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",
           "data":{
            "first": {
                "value":"恭喜你购买成功！",
                       "color":"#173177"
                   },
                   "keynote1":{
                "value":"巧克力",
                       "color":"#173177"
                   },
                   "keynote2": {
                "value":"39.8元",
                       "color":"#173177"
                   },
                   "keynote3": {
                "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                "value":"欢迎再次购买！",
                       "color":"#173177"
                   }
           }
       }*/


        $token_object=static ::get_weixin_token_memcache();
        $url="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$token_object->access_token";
        $re =  Tools::postJson($url,$p,JSON_UNESCAPED_UNICODE);
        return json_decode($re);
    }
}